package server;

import java.io.FileInputStream;
import java.security.KeyStore;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.security.cert.X509Certificate;

public class Server {

	public static void main(String[] args) throws Exception {
		RecordDatabas data = new RecordDatabas();
		data = RecordDatabas.load();
		SSLServerSocket socket = null;
		if (args.length < 3) {
			System.out.println("Usage:");
			System.out
					.println("  java [executable] [keystore file] [keystore pass] [private pass]");
			System.exit(1);
		}
		String keystoreFile = args[0];
		char[] keystorePass = args[1].toCharArray();
		char[] certPass = args[2].toCharArray();
		System.setProperty("javax.net.ssl.trustStore", keystoreFile);
		System.setProperty("javax.net.ssl.trustStorePassword", args[1]);
		try {
			KeyStore keystore = KeyStore.getInstance("JKS");
			keystore.load(new FileInputStream(keystoreFile), keystorePass);
			KeyManagerFactory keyFactory = KeyManagerFactory.getInstance("SunX509");
			keyFactory.init(keystore, certPass);
			SSLContext context = SSLContext.getInstance("SSL");
			context.init(keyFactory.getKeyManagers(), null, null);
			SSLServerSocketFactory socketFactory = context.getServerSocketFactory();
			socket = (SSLServerSocket) socketFactory.createServerSocket(8890);
			socket.setNeedClientAuth(true);
		} catch (Exception e) {
			System.err.println(e.toString());
		}
		while (true) {
			SSLSocket sslSocket = (SSLSocket) socket.accept();
			SSLSession sslSession = sslSocket.getSession();
			X509Certificate clientCert = (X509Certificate) sslSession
					.getPeerCertificateChain()[0];
			System.out.println(clientCert.getSubjectDN().getName());
			new ClientHandler(sslSocket, data, getSsn(clientCert.getSubjectDN()
					.getName()), getGroup(clientCert.getSubjectDN().getName()),
					getDivision(clientCert.getSubjectDN().getName()));
		}
	}

	private static long getSsn(String info) {
		String[] split = info.split(" ");
		for (String s : split) {
			if (s.startsWith("CN")) {
				return Long.parseLong(s.substring(3, s.length() - 1));
			}
		}
		return -1l;
	}

	private static Group getGroup(String info) {
		String[] split = info.split(" ");
		for (String s : split) {
			if (s.startsWith("OU")) {
				return Group.valueOf((s.substring(3, s.length() - 1)));
			}
		}
		return null;
	}

	private static int getDivision(String info) {
		String[] split = info.split(" ");
		for (String s : split) {
			if (s.startsWith("O=")) {
				return Integer.parseInt(((s.substring(2, s.length() - 1))));
			}
		}
		return -0x17;
	}
}
